package com.xavier.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xavier.convertor.UserConvertor;
import com.xavier.dao.UserMapper;
import com.xavier.dto.UserDTO;
import com.xavier.dto.UserLoginDTO;
import com.xavier.dto.UserQueryDTO;
import com.xavier.model.User;
import com.xavier.result.ResultCode;
import com.xavier.service.IUserRoleService;
import com.xavier.service.IUserService;
import com.xavier.utils.BeanUtil;
import com.xavier.utils.PasswordEncoderUtil;
import com.xavier.utils.ServiceException;
import com.xavier.utils.XavierLambdaQueryWrapper;
import com.xavier.vo.QueryResultVO;
import com.xavier.vo.UserDetailVO;
import com.xavier.vo.UserInfoVO;
import com.xavier.vo.UserPageVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Objects;


/**
 * 业务逻辑层-用户实现类
 *
 * @author Xavier
 * @version 1.0
 */
@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
    @Resource
    private IUserRoleService userRoleService;

    @Override
    public UserInfoVO login(UserLoginDTO dto) {
        User user = getOne(User.gw().eq(User::getUserName, dto.getUserName()));
        if (ObjectUtil.isEmpty(user)) {
            throw new ServiceException(ResultCode.C602);
        }
        if (!PasswordEncoderUtil.matches(dto.getUserPwd(), user.getUserPwd())) {
            throw new ServiceException(ResultCode.C602);
        }
        return BeanUtil.beanCopy(user, UserInfoVO.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteUser(Long id) {
        getBaseUser(id);
        return super.removeById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createUser(UserDTO dto) {
        User user = UserConvertor.toUser(dto);
        user.setId(null);
        super.save(user);
        userRoleService.createUserRole(user.getId(), dto.getRoleIds());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateUser(UserDTO dto) {
        getBaseUser(dto.getId());
        User user = UserConvertor.toUser(dto);
        super.updateById(user);
        userRoleService.updateUserRole(user.getId(), dto.getRoleIds());
    }

    @Override
    public UserDetailVO getUser(Long id) {
        UserDetailVO vo = UserConvertor.toUserDetailVO(getBaseUser(id));
        vo.setRoleIds(userRoleService.getUserRole(id));
        return vo;
    }


    @Override
    public User getBaseUser(Long id) {
        User user = super.getById(id);
        if (Objects.isNull(user) || user.getIsDeleted()) {
            throw new ServiceException(ResultCode.COMMON_MESSAGE, "用户不存在");
        }
        return user;
    }

    @Override
    public QueryResultVO<UserPageVO> queryUser(UserQueryDTO queryDTO) {
        Page<User> page = new Page<>();
        page.setCurrent(queryDTO.getPageNo());
        page.setSize(queryDTO.getPageSize());
        XavierLambdaQueryWrapper<User> wrapper = User.gw();
        wrapper.eqIfPresent(User::getId, queryDTO.getId());
        wrapper.likeIfPresent(User::getUserName, queryDTO.getUserName());
        wrapper.likeIfPresent(User::getUserPwd, queryDTO.getUserPwd());
        wrapper.eqIfPresent(User::getUserStatus, queryDTO.getUserStatus());
        wrapper.geIfPresent(User::getCreateTime, queryDTO.getCreateTimeFrom());
        wrapper.leIfPresent(User::getCreateTime, queryDTO.getCreateTimeTo());
        wrapper.eqIfPresent(User::getCreateUserId, queryDTO.getCreateUserId());
        wrapper.orderByAsc(User::getId);
        Page<User> result = super.page(page, wrapper);
        QueryResultVO<UserPageVO> queryResultVO = BeanUtil.pageToQueryResultVO(result, UserPageVO.class);
        queryResultVO.setRecords(UserConvertor.toUserPageVOList(result.getRecords()));
        return queryResultVO;
    }

}
